package com.cavy.platform.server.service;

import com.cavy.platform.server.domain.UnAvailableAgentException;
import com.cavy.platform.server.domain.UnknownOnlineAgentException;
import com.cavy.platform.server.domain.job.Job;
import com.cavy.platform.server.domain.job.PendingJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author 唐旭
 * @Date 2018/7/26
 */
@Service
@Slf4j
public class JobSender implements Runnable {
    private CopyOnWriteArrayList<PendingJob> list = new CopyOnWriteArrayList<>();
    private Thread thread = new Thread(this);
    private volatile boolean run = true;

    @PostConstruct
    public void init() {
        thread.setName("JobSender");
        thread.setDaemon(true);
        thread.start();
        log.info("任务调度线程已启动...");
    }

    @PreDestroy
    public void destroy() throws InterruptedException {
        synchronized (this) {
            run = false;
        }
        thread.join(1000);
    }

    @Override
    public void run() {
        try {
            while (run) {
                sendAll();
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage());
            thread.interrupt();
        }
    }

    private void sendAll() {
        List<PendingJob> removeList = new ArrayList<>();
        Object[] objects = list.toArray();
        for (Object item : objects) {
            PendingJob pendingJob = (PendingJob) item;
            Job next = ((PendingJob) item).getJob();
            try {
                pendingJob.dispatch();
                removeList.add(pendingJob);
            } catch (UnknownOnlineAgentException e) {
                log.warn("调度job({},{},{},{})失败,无在线的agent", next.getWorkspaceName(), next.getProjectName(), next.getPipelineName(), next.getNumber());
                //忽略没有客户端异常
            } catch (IOException e) {
                log.error("调度job({},{},{},{})失败,通信异常:{},{}", next.getWorkspaceName(), next.getProjectName(), next.getPipelineName(), next.getNumber(), e.toString(), e.getMessage());
                e.printStackTrace();
            } catch (UnAvailableAgentException e) {
                log.warn("调度job({},{},{},{})失败,无可用的agent", next.getWorkspaceName(), next.getProjectName(), next.getPipelineName(), next.getNumber());
            }
        }
        list.removeAll(removeList);
    }

    public void send(PendingJob job) {
        list.add(job);
    }
}
